<template>
  <div class="picture-list-waterfall" ref="containerRef">
    <!-- 瀑布流图片网格 -->
    <div class="masonry-container">
      <div v-for="picture in dataList" :key="picture.id" class="masonry-item">
        <!-- 单张图片 -->
        <div class="picture-card" @click="doClickPicture(picture)">
          <!-- 使用骨架屏包裹整个卡片内容 -->
          <a-skeleton :loading="imageLoading[picture.id]" active class="card-skeleton">
            <template #avatar>
              <div class="skeleton-image"></div>
            </template>
            <template #title>
              <div class="skeleton-info">
                <div class="skeleton-user">
                  <div class="skeleton-avatar"></div>
                  <div class="skeleton-text"></div>
                </div>
                <div class="skeleton-title"></div>
              </div>
            </template>
          </a-skeleton>

          <div class="image-wrapper">
            <img
              :alt="picture.name || '未命名图片'"
              :src="picture.thumbnailUrl ?? picture.url"
              loading="lazy"
              @load="onImageLoad($event, picture.id)"
              :class="{ 'image-loaded': !imageLoading[picture.id] }"
            />

            <!-- 悬浮标签 (可选) -->
            <div class="image-tags-overlay" v-if="picture.tags && picture.tags.length">
              <a-tag
                v-if="picture.tags.length > 0"
                style="
                  font-size: 14px;
                  background-color: #ffc107;
                  color: aliceblue;
                  padding: 3px 8px;
                  border-radius: 5px;
                "
              >
                <SketchOutlined />
                精选
              </a-tag>
            </div>

            <!-- 图片信息悬浮层 -->
            <div class="image-info">
              <div class="image-introduction">{{ picture.introduction ?? '暂无介绍' }}</div>
              <!-- 操作按钮 -->
              <div v-if="false" class="image-actions">
                <a-tooltip title="搜索">
                  <search-outlined @click.stop="(e) => doSearch(picture, e)" />
                </a-tooltip>
                <a-tooltip title="分享">
                  <share-alt-outlined @click.stop="(e) => doShare(picture, e)" />
                </a-tooltip>
                <a-tooltip v-if="canEdit" title="编辑">
                  <edit-outlined @click.stop="(e) => doEdit(picture, e)" />
                </a-tooltip>
                <a-tooltip v-if="canDelete" title="删除">
                  <delete-outlined @click.stop="(e) => doDelete(picture, e)" />
                </a-tooltip>
              </div>
            </div>
          </div>

          <!-- 图片下方的用户信息和互动区域 -->
          <div class="image-info-footer" v-show="!imageLoading[picture.id]">
            <!-- 用户信息 -->
            <div class="user-info">
              <a-avatar
                :size="30"
                :src="picture.userVO?.userAvatar"
                @click.stop
                class="user-avatar"
              />
              <div class="user-name text-ellipsis" @click.stop>
                {{ picture.userVO?.userName || '未知用户' }}
              </div>
            </div>

            <!-- 图片标题 -->
            <div class="image-title">{{ picture.name || '-' }}</div>

            <!-- 互动数据 -->
            <div class="interaction-data">
              <div class="interaction-item">
                <a-tooltip title="搜索">
                  <search-outlined @click.stop="(e) => doSearch(picture, e)" />
                </a-tooltip>
              </div>
              <div class="interaction-item">
                <a-tooltip :title="thumbStatus[picture.id] ? '取消点赞' : '点赞'">
                  <span @click.stop="(e) => handleThumb(picture, e)" class="thumb-icon">
                    <LikeFilled v-if="thumbStatus[picture.id]" style="color: #ff4d4f" />
                    <LikeOutlined v-else />
                  </span>
                  <span>{{ formatNumber(thumbCounts[picture.id] || 0) }}</span>
                </a-tooltip>
              </div>
              <div class="share-btn" @click.stop="(e) => doShare(picture, e)">
                <a-tooltip title="分享">
                  <ShareAltOutlined />
                </a-tooltip>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 加载更多 -->
    <div v-if="loading" class="loading-more">
      <a-spin />
      <p>加载更多中...</p>
    </div>

    <!-- 没有更多数据 -->
    <div v-if="finished && !loading && dataList.length > 0" class="no-more">没有更多图片了</div>

    <!-- 空状态 -->
    <a-empty v-if="!loading && dataList.length === 0" description="暂无图片" />

    <!-- 分享模态框 -->
    <ShareModal ref="shareModalRef" :link="shareLink || ''" title="分享图片" />
  </div>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
import {
  DeleteOutlined,
  EditOutlined,
  SearchOutlined,
  ShareAltOutlined,
  LoadingOutlined,
  EyeOutlined,
  LikeOutlined,
  LikeFilled,
  MessageOutlined,
  SketchOutlined,
} from '@ant-design/icons-vue'
import { deletePictureUsingPost } from '@/api/pictureController'
import { doThumb, undoThumb } from '@/api/thumbController'
import { message } from 'ant-design-vue'
import ShareModal from '@/components/ShareModal.vue'
import { ref, onMounted, onUnmounted, watch, reactive, h } from 'vue'

// 加载图标
const indicator = h(LoadingOutlined, { style: { fontSize: '24px' }, spin: true })

// 定义图片项接口（如果API命名空间不可用，使用自定义接口）
interface PictureVO {
  id: string | number
  name?: string
  url: string
  thumbnailUrl?: string
  category?: string
  tags?: string[]
  spaceId?: string | number
  introduction?: string
  userId?: number
  thumbCount?: number
  hasThumb?: boolean
  userVO?: {
    id?: number
    userName?: string
    userAvatar?: string
  }
}

// Props定义
interface Props {
  dataList?: PictureVO[]
  loading?: boolean
  showOp?: boolean
  onReload?: () => void
  canEdit?: boolean
  canDelete?: boolean
  onLoadMore?: () => void
  hasMore?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  dataList: () => [],
  loading: false,
  showOp: false,
  canEdit: false,
  canDelete: false,
  hasMore: true,
})

// 用于追踪每个图片的加载状态
const imageLoading = reactive<Record<string | number, boolean>>({})
// 用于追踪每个图片的点赞状态
const thumbStatus = reactive<Record<string | number, boolean>>({})
// 用于追踪每个图片的点赞数
const thumbCounts = reactive<Record<string | number, number>>({})

// 分享弹窗引用
const shareModalRef = ref<any>(null)
// 分享链接
const shareLink = ref<string>('')
// 容器引用，用于监听滚动
const containerRef = ref<HTMLElement | null>(null)
// 是否已加载全部数据
const finished = ref(false)
// 滚动距离阈值
const scrollThreshold = 300
// 节流控制
let isLoadingMore = false
// 滚动定时器
let scrollTimer: number | null = null

// 格式化数字（例如：1000 -> 1k）
const formatNumber = (num: number): string => {
  if (num >= 1000) {
    return (num / 1000).toFixed(1) + 'k'
  }
  return num.toString()
}

// 监听滚动事件，实现无限加载
const handleScroll = () => {
  if (props.loading || finished.value || isLoadingMore) return

  // 使用节流控制滚动检查频率
  if (scrollTimer !== null) {
    clearTimeout(scrollTimer)
  }

  scrollTimer = window.setTimeout(() => {
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
    const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight
    const clientHeight = document.documentElement.clientHeight || window.innerHeight

    // 降低触发阈值，让滚动更容易触发加载
    const scrollThreshold = clientHeight * 1.0 // 增加到整个视口高度
    const distanceToBottom = scrollHeight - scrollTop - clientHeight

    console.log('滚动检测：', {
      scrollTop,
      scrollHeight,
      clientHeight,
      distanceToBottom,
      threshold: scrollThreshold,
      shouldLoad: distanceToBottom < scrollThreshold,
    })

    // 当距离底部还有1个视口高度时就开始加载更多
    if (distanceToBottom >= 0 && distanceToBottom < scrollThreshold) {
      loadMore()
    }
  }, 100) // 减少延迟
}

// 初始化新加载图片的加载状态
watch(
  () => props.dataList,
  (newList) => {
    newList.forEach((picture) => {
      if (imageLoading[picture.id] === undefined) {
        imageLoading[picture.id] = true
      }
      // 初始化点赞状态和点赞数
      if (thumbStatus[picture.id] === undefined) {
        thumbStatus[picture.id] = picture.hasThumb || false
      }
      if (thumbCounts[picture.id] === undefined) {
        thumbCounts[picture.id] = picture.thumbCount || 0
      }
    })
  },
  { immediate: true }
)

// 加载更多数据
const loadMore = () => {
  if (props.onLoadMore && !finished.value && !props.loading && !isLoadingMore) {
    isLoadingMore = true
    props.onLoadMore()
    // 给一个安全的超时，防止长时间不释放
    setTimeout(() => {
      isLoadingMore = false
    }, 2000)
  }
}

// 图片加载完成后的处理
const onImageLoad = (event: Event, id: string | number) => {
  // 将图片标记为已加载
  imageLoading[id] = false

  // 触发一次滚动检查，以防图片加载后页面高度变化
  handleScroll()
}

// 组件挂载时添加滚动监听
onMounted(() => {
  window.addEventListener('scroll', handleScroll)

  // 初始化时检查一次是否需要加载更多
  // 适用于初始内容不足以填满页面的情况
  setTimeout(() => {
    handleScroll()
  }, 500)
})

// 组件卸载时移除滚动监听
onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll)
  if (scrollTimer !== null) {
    clearTimeout(scrollTimer)
  }
})

// 监听外部hasMore变化
watch(
  () => props.hasMore,
  (newVal: boolean | undefined) => {
    finished.value = !newVal
    isLoadingMore = false
  }
)

// 监听loading状态变化
watch(
  () => props.loading,
  (newVal: boolean) => {
    if (!newVal) {
      isLoadingMore = false
    }
  }
)

// 跳转至图片详情
const router = useRouter()
const doClickPicture = (picture: PictureVO) => {
  const url = `${window.location.origin}/picture/${picture.id}`
  window.open(url, '_blank')
}

// 编辑
const doEdit = (picture: PictureVO, e: Event) => {
  // 阻止向上冒泡
  e.stopPropagation()
  router.push({
    path: '/picture/addPicture',
    query: {
      id: picture.id,
      spaceId: picture.spaceId,
    },
  })
}

// 删除
const doDelete = async (picture: PictureVO, e: Event) => {
  // 阻止向上冒泡
  e.stopPropagation()
  const id = picture.id
  if (!id) {
    return
  }
  const res = await deletePictureUsingPost({ id: typeof id === 'string' ? parseInt(id) : id })
  if (res.data.code === 0) {
    message.success('删除成功')
    // 让外层刷新
    if (props.onReload) {
      props.onReload()
    }
  } else {
    message.error('删除失败')
  }
}

// 搜索
const doSearch = (picture: PictureVO, e: Event) => {
  e.stopPropagation()
  message.info('图片搜索功能已关闭！')
  // window.open(`/searchPicture?pictureId=${picture.id}`)
}

// 分享
const doShare = (picture: PictureVO, e: Event) => {
  e.stopPropagation()
  shareLink.value = `${window.location.protocol}//${window.location.host}/picture/${picture.id}`
  if (shareModalRef.value) {
    shareModalRef.value.showModal()
  }
}

// 处理点赞/取消点赞
const handleThumb = async (picture: PictureVO, e: Event) => {
  e.stopPropagation()
  const pictureId = picture.id

  try {
    if (!thumbStatus[pictureId]) {
      // 点赞
      const res = await doThumb({ pictureId })
      if (res.data?.code === 0 && res.data?.data === true) {
        thumbStatus[pictureId] = true
        thumbCounts[pictureId] = (thumbCounts[pictureId] || 0) + 1
        message.success('点赞成功')
      } else {
        message.error('点赞失败：' + (res.data?.message || '未知错误'))
      }
    } else {
      // 取消点赞
      const res = await undoThumb({ pictureId })
      if (res.data?.code === 0) {
        thumbStatus[pictureId] = false
        thumbCounts[pictureId] = Math.max(0, (thumbCounts[pictureId] || 0) - 1)
        message.success('已取消点赞')
      } else {
        message.error('取消点赞失败：' + (res.data?.message || '未知错误'))
      }
    }
  } catch (error) {
    message.error('操作失败，请稍后再试')
    console.error('点赞操作失败:', error)
  }
}
</script>

<style scoped>
.picture-list-waterfall {
  padding: 40px;
}

/* 瀑布流容器 */
.masonry-container {
  column-count: 5;
  column-gap: 22px;
  width: 100%;
}

.masonry-item {
  break-inside: avoid;
  margin-bottom: 24px;
}

@media (max-width: 1400px) {
  .masonry-container {
    column-count: 5;
  }
}

@media (max-width: 1200px) {
  .masonry-container {
    column-count: 5;
  }
}

@media (max-width: 992px) {
  .masonry-container {
    column-count: 3;
  }
}

@media (max-width: 768px) {
  .masonry-container {
    column-count: 2;
  }
}

@media (max-width: 576px) {
  .masonry-container {
    column-count: 2;
    column-gap: 8px;
  }

  .masonry-item {
    margin-bottom: 6px;
  }

  .picture-list-waterfall {
    padding: 8px;
  }
}

.picture-card {
  position: relative;
  width: 100%;
  cursor: pointer;
  border-radius: 12px;
  overflow: hidden;
  background-color: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: transform 0.2s, box-shadow 0.2s;
}

.picture-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.image-wrapper {
  border: 1px solid #d3d3d3;
  position: relative;
  width: 100%;
  overflow: hidden;
}

.image-wrapper img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.3s, opacity 0.3s;
}

.image-wrapper img:hover {
  transform: scale(1.05);
}

.image-loading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(240, 240, 240, 0.8);
  z-index: 2;
}

.image-loaded {
  opacity: 1;
}

.image-wrapper img:not(.image-loaded) {
  opacity: 0;
}

/* 骨架屏样式 */
.card-skeleton {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  background-color: #fff;
  border-radius: 12px;
  overflow: hidden;
}

.card-skeleton :deep(.ant-skeleton-avatar) {
  width: 100% !important;
  height: calc(100% - 80px) !important;
  border-radius: 12px 12px 0 0;
  margin: 0;
}

.card-skeleton :deep(.ant-skeleton-title) {
  margin: 0 !important;
  height: auto !important;
}

.skeleton-image {
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, #f5f5f5 25%, #ebebeb 37%, #f5f5f5 63%);
  background-size: 400% 100%;
  animation: skeleton-loading 1.4s ease infinite;
}

.skeleton-info {
  padding: 12px;
  background: #fff;
}

.skeleton-user {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.skeleton-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(90deg, #f5f5f5 25%, #ebebeb 37%, #f5f5f5 63%);
  background-size: 400% 100%;
  animation: skeleton-loading 1.4s ease infinite;
}

.skeleton-text {
  width: 100px;
  height: 16px;
  border-radius: 4px;
  background: linear-gradient(90deg, #f5f5f5 25%, #ebebeb 37%, #f5f5f5 63%);
  background-size: 400% 100%;
  animation: skeleton-loading 1.4s ease infinite;
}

.skeleton-title {
  width: 80%;
  height: 16px;
  border-radius: 4px;
  background: linear-gradient(90deg, #f5f5f5 25%, #ebebeb 37%, #f5f5f5 63%);
  background-size: 400% 100%;
  animation: skeleton-loading 1.4s ease infinite;
}

@keyframes skeleton-loading {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

/* 图片标签悬浮层 */
.image-tags-overlay {
  position: absolute;
  top: 8px;
  left: 8px;
  display: flex;
  gap: 4px;
  z-index: 1;
}

/* 悬浮信息层 */
.image-info {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 10px;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.4));
  color: #fff;
  opacity: 0;
  transition: opacity 0.3s;
  z-index: 2;
}

.picture-card:hover .image-info {
  opacity: 1;
}

.image-info .image-introduction {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #fff;
}

.image-info .image-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-bottom: 5px;
}

.image-actions {
  display: flex;
  gap: 15px;
  color: #fff;
  font-size: 16px;
}

.image-actions .anticon {
  opacity: 0.8;
  transition: opacity 0.2s;
}

.image-actions .anticon:hover {
  opacity: 1;
}

/* 图片下方的信息区域 */
.image-info-footer {
  background-color: #fff;
  padding: 12px;
  position: relative;
}

/* 用户信息样式 */
.user-info {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.user-avatar {
  cursor: pointer;
}

.user-avatar:hover {
  opacity: 0.9;
}

.user-name {
  font-size: 15px;
  font-weight: 500;
  color: #333;
  cursor: pointer;
}

.user-name:hover {
  color: #1890ff;
}

/* 图片标题 - 底部区域 */
.image-info-footer .image-title {
  font-size: 14px;
  margin-bottom: 5px;
  color: #333;
  font-weight: 500;
}

/* 互动数据 */
.interaction-data {
  display: flex;
  align-items: center;
  padding: 10px 10px 2px 10px;
  justify-content: space-between;
  font-size: 13px;
  color: #666;
}

.interaction-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.share-btn {
  cursor: pointer;
  color: #666;
  font-size: 14px;
}

.share-btn:hover {
  color: #1890ff;
}

/* 点赞按钮样式 */
.thumb-icon {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s;
  margin-right: 4px;
}

.thumb-icon:hover {
  transform: scale(1.2);
}

/* 文字溢出省略 */
.text-ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 加载状态和空状态 */
.loading-more {
  text-align: center;
  margin: 20px 0;
  padding: 20px 0;
}

.loading-more p {
  margin-top: 8px;
  color: #666;
}

.no-more {
  margin-top: 16px;
  text-align: center;
  color: #666;
  padding: 16px;
  font-size: 14px;
}
</style>
